#include "YaoAV/YaoReader.h"
#include <vector>

extern "C"
{
#include "libavformat/avformat.h"
#include "libavutil/avutil.h"
}

int main()
{
    //read
    YaoReader reader;
    int ret = reader.Open("/Users/yaoyao/Downloads/IMG_9048.mp4");

    if(ret)
    {
        printf("reader.Open fail \n");
        return -1;
    }

    int videoStreamIndex = reader.GetStreamIndex(AVMEDIA_TYPE_VIDEO);

    //decoder
    YaoStream stream;
    reader.GetStream(&stream, videoStreamIndex);
    YaoFFmpegDecoder *realDecoder = new YaoFFmpegDecoder(&stream);
    realDecoder->Open();

    //write yuv file
    FILE * f = fopen("/Users/yao/Downloads/zzsin_1920x1080_30fps_30s_aac_48000_stereo.yuv", "wb");

    while (true){
        YaoPacket packet;
        YaoFrame frame;
        int ret = reader.Read(&packet);

        if(ret != 0){
            break;
        }

        if(packet.GetPktStreamIndex() != videoStreamIndex) {
            continue;
        }

        //decode
        ret = realDecoder->SendPacket(&packet);
        if(ret){
            continue;
        }
        while (true){
            ret = realDecoder->ReceiveFrame(&frame);
            if(ret != 0){
                break;
            }

            frame.VideoPrint();
            int width = frame.avFrame->width;
            int height = frame.avFrame->height;
            unsigned char *y = (unsigned char *) malloc(width * height);
            unsigned char *u = (unsigned char *) malloc(width / 2 * height / 2);
            unsigned char *v = (unsigned char *) malloc(width / 2 * height / 2);
            frame.GetU(u);
            frame.GetV(v);
            frame.GetY(y);

            fwrite(y, width * height, 1, f);
            fwrite(u, width / 2 * height / 2, 1, f);
            fwrite(v, width / 2 * height / 2, 1, f);

        }
    }

    realDecoder->SendPacket(nullptr);
    while (true){
        YaoFrame frame;
        int ret = realDecoder->ReceiveFrame(&frame);
        if(ret != 0){
            break;
        }

        frame.VideoPrint();
        int width = frame.avFrame->width;
        int height = frame.avFrame->height;
        unsigned char * y = (unsigned char *)malloc(width * height);
        unsigned char * u = (unsigned char *)malloc(width/2 * height/2);
        unsigned char * v = (unsigned char *)malloc(width/2 * height/2);
        frame.GetU(u);
        frame.GetV(v);
        frame.GetY(y);

        fwrite(y, width * height, 1, f);
        fwrite(u, width/2 * height/2, 1, f);
        fwrite(v, width/2 * height/2, 1, f);
    }

    reader.Close();
    delete realDecoder;
    fclose(f);

}
